﻿/*--------------------------------------------------------------------------------------
 *
 * 用途：
 * 
 * 创建人： 
 * 
 * 创建时间： 
 * 
 * 
 *-------------------------------------------------------------------------------------- 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AjaxControlToolkit;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Diagnostics;
using System.ComponentModel;

[assembly: System.Web.UI.WebResource("Kevin.Controls.DatePicker.DatePicker.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Kevin.Controls.DatePicker.Calendar.css", "text/css", PerformSubstitution = true)]
[assembly: System.Web.UI.WebResource("Kevin.Controls.DatePicker.arrow-left.gif", "image/gif")]
[assembly: System.Web.UI.WebResource("Kevin.Controls.DatePicker.arrow-right.gif", "image/gif")]
[assembly: System.Web.UI.WebResource("Kevin.Controls.DatePicker.datePicker.gif", "image/gif")]
namespace Kevin.Controls
{
    /// <summary>
    /// 日期类型录入控件
    /// </summary>

    [RequiredScript(typeof(CommonToolkitScripts), 0)]
    [RequiredScript(typeof(DateTimeScripts), 1)]
    [RequiredScript(typeof(PopupExtender), 2)]
    [RequiredScript(typeof(AnimationScripts), 3)]
    [RequiredScript(typeof(ThreadingScripts), 4)]
    [ClientCssResource("Kevin.Controls.DatePicker.Calendar.css")]
    [ClientScriptResource("Kevin.Controls.DatePicker", "Kevin.Controls.DatePicker.DatePicker.js")]    
    public class DatePicker:ScriptControlBase
    {
        public DatePicker()
            : base(true,HtmlTextWriterTag.Div)
        {
        }


        #region Properties
        [ClientPropertyName("tagetControlID")]
        [ExtenderControlProperty]
        public string TagetControlID
        {
            get 
            { 
                string id=GetPropertyValue<string>("TagetControlID", "");
                Control ctr = this.FindControlByPath(this, id);
                if (ctr != null)
                {
                    id = ctr.ClientID;
                    
                }
                return id; 
            }
            set { SetPropertyValue<string>("TagetControlID", value); }
        }

        /// <summary>
        /// 日期控件显示格式
        /// </summary>
        [ClientPropertyName("DateFormat")]
        [ExtenderControlProperty]
        [EditorBrowsable( EditorBrowsableState.Never)]
        public DateFormart DateFormat
        {
            get { return GetPropertyValue<DateFormart>("DateFormat", DateFormart.Date); }
            set { SetPropertyValue<DateFormart>("DateFormat", value); }
        }

        /// <summary>
        /// 是否显示日历图标 - 默认值 true
        /// </summary>
        [ClientPropertyName("ShowCelenderICO")]
        [ExtenderControlProperty]
        public bool ShowCelenderICO
        {
            get { return GetPropertyValue<bool>("ShowCelenderICO", true); }
            set { SetPropertyValue<bool>("ShowCelenderICO", value); }
        }

        /// <summary>
        /// Format string used to display the selected date. The default value is "d"
        /// </summary>
        [DefaultValue("yyyy-MM-dd")]
        [ExtenderControlProperty]
        [ClientPropertyName("format")]
        public virtual string Format
        {
            get { return GetPropertyValue("Format", "yyyy-MM-dd"); }
            set { 
                SetPropertyValue("Format", value); 
                if(value.Contains(":"))
                {
                    this.DateFormat = Kevin.Controls.DateFormart.DateTime;
                }
            }
        }

        /// <summary>
        /// Format string used to display today's date. The default value is "MMMM d, yyyy"
        /// </summary>
        [DefaultValue("yyyy-MM-dd")]
        [ExtenderControlProperty]
        [ClientPropertyName("todaysDateFormat")]
        public virtual string TodaysDateFormat
        {
            get { return GetPropertyValue("TodaysDateFormat", "yyyy-MM-dd"); }
            set { SetPropertyValue("TodaysDateFormat", value); }
        }

        /// <summary>
        /// Format string used to display Days Mode Title. The default value is "MMMM, yyyy"
        /// </summary>
        [DefaultValue("MM,yyyy")]
        [ExtenderControlProperty]
        [ClientPropertyName("daysModeTitleFormat")]
        public virtual string DaysModeTitleFormat
        {
            get { return GetPropertyValue("DaysModeTitleFormat", "MM,yyyy"); }
            set { SetPropertyValue("DaysModeTitleFormat", value); }
        }

        /// <summary>
        /// Whether time should be cleared in edited date/time
        /// </summary>
        [DefaultValue(false)]
        [ExtenderControlProperty]
        [ClientPropertyName("clearTime")]
        public virtual bool ClearTime
        {
            get { return GetPropertyValue("ClearTime", false); }
            set { SetPropertyValue("ClearTime", value); }
        }

        /// <summary>
        /// Whether this behavior is available for the current element
        /// </summary>
        [DefaultValue(true)]
        [ExtenderControlProperty]
        [ClientPropertyName("enabled")]
        public virtual bool EnabledOnClient
        {
            get { return GetPropertyValue("EnabledOnClient", true); }
            set { SetPropertyValue("EnabledOnClient", value); }
        }

        /// <summary>
        /// Whether this behavior is can be input by keyboad for the current element
        /// </summary>
        [DefaultValue(false)]
        [ExtenderControlProperty]
        [ClientPropertyName("readOnly")]
        public virtual bool ReadOnly
        {
            get { return GetPropertyValue<bool>("readOnly", false); }
            set { SetPropertyValue<bool>("readOnly", value); }
        }

        /// <summary>
        /// Whether changing modes is animated
        /// </summary>
        [DefaultValue(true)]
        [ExtenderControlProperty]
        [ClientPropertyName("animated")]
        public virtual bool Animated
        {
            get { return GetPropertyValue("Animated", true); }
            set { SetPropertyValue("Animated", value); }
        }

        /// <summary>
        /// Gets or sets the first day of week
        /// </summary>
        [DefaultValue(FirstDayOfWeek.Default)]
        [ExtenderControlProperty]
        [ClientPropertyName("firstDayOfWeek")]
        public virtual FirstDayOfWeek FirstDayOfWeek
        {
            get { return GetPropertyValue("FirstDayOfWeek", FirstDayOfWeek.Default); }
            set { SetPropertyValue("FirstDayOfWeek", value); }
        }

        /// <summary>
        /// The ID of a control to show the calendar popup when clicked. If this value is not set, the calendar will pop up when the textbox receives focus
        /// </summary>
        [DefaultValue("")]
        [ExtenderControlProperty]
        [ClientPropertyName("button")]
        [ElementReference]
        [IDReferenceProperty]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", Justification = "Following ASP.NET AJAX pattern")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public virtual string PopupButtonID
        {
            get { return GetPropertyValue("PopupButtonID", string.Empty); }
            set { SetPropertyValue("PopupButtonID", value); }
        }


        /// <summary>
        /// Gets or sets the popup position of the calendar. The default value is BottomLeft
        /// </summary>
        [ExtenderControlProperty]
        [ClientPropertyName("popupPosition")]
        [DefaultValue(CalendarPosition.BottomLeft)]
        [Description("Indicates where you want the calendar displayed, bottom or top of the textbox.")]
        public virtual CalendarPosition PopupPosition
        {
            get { return GetPropertyValue("PopupPosition", CalendarPosition.BottomLeft); }
            set { SetPropertyValue("PopupPosition", value); }
        }

        /// <summary>
        /// Gets or sets the date that the calendar is initialized with
        /// </summary>
        [DefaultValue(null)]
        [ExtenderControlProperty]
        [ClientPropertyName("selectedDate")]
        public DateTime? SelectedDate
        {
            get { return GetPropertyValue<DateTime?>("SelectedDate", null); }
            set { SetPropertyValue<DateTime?>("SelectedDate", value); }
        }

        /// <summary>
        /// Gets or sets the default view of the calender. The default value is Days.
        /// </summary>
        [DefaultValue(CalendarDefaultView.Days)]
        [ExtenderControlProperty]
        [ClientPropertyName("defaultView")]
        [Description("Default view of the calendar when it first pops up.")]
        public virtual CalendarDefaultView DefaultView
        {
            get { return GetPropertyValue("DefaultView", CalendarDefaultView.Days); }
            set { SetPropertyValue("DefaultView", value); }
        }

        /// <summary>
        /// Gets or sets the client script that executes immediately before the calendar is displayed
        /// </summary>
        [DefaultValue("")]
        [ExtenderControlEvent]
        [ClientPropertyName("showing")]
        public virtual string OnClientShowing
        {
            get { return GetPropertyValue("OnClientShowing", string.Empty); }
            set { SetPropertyValue("OnClientShowing", value); }
        }

        /// <summary>
        /// Gets or sets the client script that executes immediately after the calendar is displayed
        /// </summary>
        [DefaultValue("")]
        [ExtenderControlEvent]
        [ClientPropertyName("shown")]
        public virtual string OnClientShown
        {
            get { return GetPropertyValue("OnClientShown", string.Empty); }
            set { SetPropertyValue("OnClientShown", value); }
        }

        /// <summary>
        /// Gets or sets the client script that executes immediately before the calendar is hidden
        /// </summary>
        [DefaultValue("")]
        [ExtenderControlEvent]
        [ClientPropertyName("hiding")]
        public virtual string OnClientHiding
        {
            get { return GetPropertyValue("OnClientHiding", string.Empty); }
            set { SetPropertyValue("OnClientHiding", value); }
        }

        /// <summary>
        /// Gets or sets the client script that executes immediately after the calendar is hidden
        /// </summary>
        [DefaultValue("")]
        [ExtenderControlEvent]
        [ClientPropertyName("hidden")]
        public virtual string OnClientHidden
        {
            get { return GetPropertyValue("OnClientHidden", string.Empty); }
            set { SetPropertyValue("OnClientHidden", value); }
        }

        /// <summary>
        /// Gets or sets the script that executes when a new date is selected
        /// </summary>
        [DefaultValue("")]
        [ExtenderControlEvent]
        [ClientPropertyName("dateSelectionChanged")]
        public virtual string OnClientDateSelectionChanged
        {
            get { return GetPropertyValue("OnClientDateSelectionChanged", string.Empty); }
            set { SetPropertyValue("OnClientDateSelectionChanged", value); }
        }
        /// <summary>
        /// 自定义日期按钮图片URL
        /// </summary>
        [Description("日期按钮图片URL")]
        public string ImgButtonURL
        {
            get { return GetPropertyValue("ImgButtonURL", Page.ClientScript.GetWebResourceUrl(this.GetType(), "Kevin.Controls.DateTextBox.datePicker.gif")); }
            set { SetPropertyValue("ImgButtonURL", value); }
        }
        [Description("设置/获取本控件的日期值")]
        public DateTime Value
        {
            get;
            set;
        }

        [DefaultValue(false)]
        //[ExtenderControlEvent]
        //[ClientPropertyName("required")]
        public bool Required
        {
            get { return GetPropertyValue("required", false); }
            set { SetPropertyValue("required", value); }
        }
        [DefaultValue("")]
        //[ExtenderControlEvent]
        //[ClientPropertyName("requiredMessage")]
        public string RequiredMessage
        {
            get { return GetPropertyValue("requiredMessage", ""); }
            set { SetPropertyValue("requiredMessage", value); }
        }

        public string ValidatorGroup
        {
            get;
            set;
        }

        #endregion

        #region override methods

        private ScriptManager sm;

        /*
        protected override void OnPreRender(EventArgs e)
        {
            if (!this.DesignMode)
            {
                Page.ClientScript.GetCallbackEventReference(this, "", "", "");
                
                TextBox txt = new TextBox();
                if (this.Value != DateTime.MinValue )
                {
                    txt.Text = this.Value.ToString(this.Format);
                    //switch (this.DateFormat)
                    //{
                    //    case DateFormart.Date:
                    //        txt.Text = Value.ToString("yyyy-MM-dd");
                    //        break;
                    //    case DateFormart.DateTime:
                    //        txt.Text = Value.ToString("yyyy-MM-dd hh:mm:ss");
                    //        break;
                    //}                    
                }
                txt.ID = "txtDate";
                
                this.Controls.Add(txt);
                if (this.ShowCelenderICO)
                {
                    ImageButton img = new ImageButton();
                    img.ID = "imgDate";
                    img.ImageUrl = ImgButtonURL;
                    img.Height = 17;
                    img.Width = 14;
                    img.CausesValidation = false;
                    this.Controls.Add(img);
                }

                if (this.Required)
                {
                    RequiredFieldValidator val = new RequiredFieldValidator();
                    val.ID = "_RequiredFieldValidator";
                    val.ControlToValidate = txt.ID;
                    val.ErrorMessage = string.IsNullOrEmpty(this.RequiredMessage)?"日期不能为空":this.RequiredMessage;
                    val.ValidationGroup = this.ValidatorGroup;
                    val.EnableClientScript = true;
                    val.SetFocusOnError = true;
                    this.Controls.Add(val);
                }
                
            }            
            base.OnPreRender(e);
        }
        //*/

        protected override void LoadClientState(string clientState)
        {
            if (this.DateFormat == DateFormart.DateTime)  this.Value = DateTime.Parse(clientState);
            if (this.DateFormat == DateFormart.Date) this.Value = DateTime.Parse(clientState).Date;
            
        }

        protected override string SaveClientState()
        {
            if (this.Value != null && this.Value !=DateTime.MinValue)
            {
                return this.Value.ToString(this.Format);
                if (this.DateFormat == DateFormart.DateTime) return this.Value.ToString();
                if (this.DateFormat == DateFormart.Date) return this.Value.ToShortDateString();
            }
           return base.SaveClientState();
        }      
        #endregion

        #region Private Methodes

        

        #endregion

        #region helper

        /// <summary>
        /// Retrieves the property value from the ViewState
        /// </summary>
        /// <typeparam name="V">Type of value</typeparam>
        /// <param name="propertyName">Property to retrieve</param>
        /// <param name="nullValue">value to be used in case it's not initialised.</param>
        /// <returns></returns>
        [DebuggerStepThrough]
        protected V GetPropertyValue<V>(string propertyName, V nullValue)
        {
            if (ViewState[propertyName] == null)
            {
                return nullValue;
            }
            return (V)ViewState[propertyName];
        }


        /// <summary>
        /// Save the property value in the ViewState
        /// </summary>
        /// <typeparam name="V">Property type</typeparam>
        /// <param name="propertyName">Property name</param>
        /// <param name="value">Value</param>
        [DebuggerStepThrough]
        protected void SetPropertyValue<V>(string propertyName, V value)
        {
            ViewState[propertyName] = value;
        }
        private Control FindControlByPath(Control rootControl, string idPath)
        {
            int depth = 0;
            string[] idPaths = idPath.Split('.');
            while (idPaths.Length > depth)
            {
                rootControl = rootControl.FindControl(idPaths[depth]);
                depth++;
            }
            return rootControl;
        }
        #endregion

        
    }
}
